#include "Can.h"
#include "CanIf.h"

typedef void (*CanIf_TxCallBack_t)(PduIdType);

#if defined(AUTOSAR_CANIF_VERSION_403)
typedef void (*CanIf_RxCallBack_t)(Can_HwHandleType, Can_IdType, uint8, const uint8 *);
#else
typedef void (*CanIf_RxCallBack_t)(const Can_HwType *, const PduInfoType *);
#endif

#if (defined(AUTOSAR_CANIF_VERSION_421)) || (defined(AUTOSAR_CANIF_VERSION_403))
typedef void (*CanIf_CtrlModeIndication_t)(uint8, canif_controller_mode_type);
#else
typedef void (*CanIf_CtrlModeIndication_t)(uint8, Can_ControllerStateType);
#endif

typedef void (*CanIf_CtrlBusOffCallBack_t)(uint8);

static CanIf_TxCallBack_t Demo_TxCallBack;
static CanIf_RxCallBack_t Demo_RxCallBack;
static CanIf_CtrlModeIndication_t Demo_CtrlModeIndication;
static CanIf_CtrlBusOffCallBack_t Demo_CtrlBusOffCallBack;

void CanIf_TxConfirmation(VAR(PduIdType, AUTOMATIC) canTxPduId)
{
	if(Demo_TxCallBack)
		Demo_TxCallBack(canTxPduId);
}

#if defined(AUTOSAR_CANIF_VERSION_403)
void CanIf_RxIndication(VAR(Can_HwHandleType, AUTOMATIC) hrh, \
		VAR(Can_IdType, AUTOMATIC) canId, \
		VAR(uint8, AUTOMATIC) canDlc, \
		P2VAR(uint8, AUTOMATIC, AUTOMATIC) canSduPtr)
{
	if(Demo_RxCallBack)
		Demo_RxCallBack(hrh, canId, canDlc, canSduPtr);
}
#else
void CanIf_RxIndication(P2VAR(Can_HwType, AUTOMATIC, AUTOMATIC) Mailbox, \
		P2VAR(PduInfoType, AUTOMATIC, AUTOMATIC) PduInfoPtr)
{
	if(Demo_RxCallBack)
		Demo_RxCallBack(Mailbox, PduInfoPtr);
}
#endif

#if (defined(AUTOSAR_CANIF_VERSION_421)) || (defined(AUTOSAR_CANIF_VERSION_403))
void CanIf_ControllerModeIndication(VAR(uint8, AUTOMATIC) ControllerId,
		VAR(CanIf_ControllerModeType, AUTOMATIC) ControllerMode)
#else
void CanIf_ControllerModeIndication(VAR(uint8, AUTOMATIC) ControllerId,
		VAR(CanIf_ControllerModeType, AUTOMATIC) ControllerMode)
#endif
{
	if(Demo_CtrlModeIndication)
		Demo_CtrlModeIndication(ControllerId, ControllerMode);
}

void CanIf_ControllerBusOff(VAR(uint8, AUTOMATIC) ControllerId)
{
	if(Demo_CtrlBusOffCallBack)
		Demo_CtrlBusOffCallBack(ControllerId);
}

void setup_canif_callback_funciton(void)
{
	Demo_RxCallBack = (CanIf_RxCallBack_t)&canif_rx_indication;
	Demo_TxCallBack = (CanIf_TxCallBack_t)&canif_tx_confirmation;
	Demo_CtrlModeIndication = (CanIf_CtrlModeIndication_t)&canif_controller_mode_indication;
	Demo_CtrlBusOffCallBack = (CanIf_CtrlBusOffCallBack_t)&canif_controller_bus_off;
}

void can_init(const Can_ConfigType *Can_ConfigPtr) {
	Can_Init(Can_ConfigPtr);
	setup_canif_callback_funciton();
}
